<template>
  <div style="height: 100%;">
    <el-input
      class="tree-search"
      placeholder="输入关键字进行过滤"
      v-model="filterText"
      size="small"
      style="margin-bottom: 5px;"
    ></el-input>
    <div class="treeDiv" :style="{ height: height }">
      <el-tree
        ref="tree"
        :node-key="defaultPropsNew.id"
        :data="treeData"
        :expand-on-click-node="expandOnClickNode"
        :default-expanded-keys="expandedKeys"
        :props="defaultPropsNew"
        :show-checkbox="showCheckbox"
        :highlight-current="highlightCurrent"
        :current-node-key="currentNodeKey"
        :check-strictly="checkStrictly"
        @check-change="handleCheckChange"
      >
        <span
          class="custom-tree-node"
          style="width: 100%;"
          slot-scope="{ node, data }"
          @click="nodeClick(node, data)"
          @mouseenter="showButton && nodeMouseenter(node, data)"
          @mouseleave="showButton && nodeMouseleave(node, data)"
        >
          <span
            class="iconfont db-bold position-r icon-dizhi blue500"
            style="top: 2px;"
            v-if="showIcon"
          ></span>
          {{ node.label }}
          <span v-if="data.deviceStatusVo && isShowDevice">
            <span
              class="iconfont icon-kongzhiqi1 font-20 position-r"
              style="top: 2px;"
              :class="deviceStatusObj[data.deviceStatusVo.deviceStatus].class2"
            ></span>
            <!-- <span class="font-14 blue500">({{ data.deviceStatusVo.deviceName }})</span> -->
            <!-- <el-badge is-dot :type="deviceStatusObj[data.deviceStatusVo.deviceStatus].type">

                        </el-badge> -->
          </span>
          <span class="treeBtn" v-if="showButton && data.show">
            <div v-for="(item, index) in treeBtnList" :key="index">
              <el-tooltip
                class="item"
                effect="dark"
                :content="item.name"
                placement="top"
                v-if="
                  !data.treeButton || data.treeButton.indexOf(item.type) > -1
                "
              >
                <span
                  class="iconfont"
                  :class="item.class"
                  @click.stop="nodeBtnHandle(item.type, node, data)"
                ></span>
              </el-tooltip>
            </div>
          </span>
        </span>
      </el-tree>
    </div>
  </div>
</template>

<script>
export default {
  props: {
    //高度
    height: {
      type: [String, Object],
      default: '',
    },
    // 选项数据
    options: {
      type: Array,
      default: () => {
        return []
      },
    },
    //请求地址
    url: {
      type: String,
      default: '/location/tree',
    },
    expandOnClickNode: {
      type: Boolean,
      default: true,
    },
    //默认展开多少层 0-不展开
    expandedLevel: {
      type: Number,
      default: 0,
    },
    // 树节点配置选项
    defaultProps: {
      type: Object,
      default: () => ({
        label: 'label',
        children: 'children',
        id: 'id',
      }),
    },
    //是否要显示多选
    showCheckbox: {
      type: Boolean,
      default: false,
    },
    //在显示复选框的情况下，是否严格的遵循父子不互相关联的做法，默认为 false
    checkStrictly: {
      type: Boolean,
      default: false,
    },
    //是否checkbox为单选
    checkRadio: {
      type: Boolean,
      default: false,
    },
    //是否显示按钮
    showButton: {
      type: Boolean,
      default: false,
    },
    //加载图标状态
    loading: {
      type: Boolean,
      default: false,
    },
    //是否要展示设备信息
    isShowDevice: {
      type: Boolean,
      default: false,
    },
    //当前是否高亮显示
    highlightCurrent: {
      type: Boolean,
      default: false,
    },
    //高亮的节点key
    currentNodeKey: {
      type: String || Number,
      default: '',
    },
    //默认选中第一个
    defaultSelectFirst: {
      type: Boolean,
      default: false,
    },
    //最上级节点ID
    topNodeId: {
      type: [Number, String],
      default: '0',
    },
    //是否展示图标
    showIcon: {
      type: Boolean,
      default: true,
    },
  },
  computed: {
    defaultPropsNew() {
      let defaultData = {
        label: 'label',
        children: 'children',
        id: 'id',
      }
      if (JSON.stringify(this.defaultProps) == JSON.stringify(defaultData))
        return defaultData
      if (Object.keys(this.defaultProps).length > 0) {
        for (let i in this.defaultProps) {
          defaultData[i] = this.defaultProps[i]
        }
      }
      return defaultData
    },
    socketMsgs() {
      return this.$socketPublic.state.msg
    },
  },
  watch: {
    filterText(val) {
      // this.$refs.tree.filter(val);
      this.filter(val)
    },
    socketMsgs: {
      //处理接收到的消息
      handler: function () {
        if (!this.isShowDevice) return
        let that = this
        that.toDoSocket(that.socketMsgs.data)
      },
    },
    currentNodeKey(newVal) {
      if (!this.highlightCurrent) return
      if (!newVal) return
      this.$nextTick(() => {
        this.$refs.tree.setCurrentKey(newVal)
      })
    },
  },
  data() {
    return {
      filterText: '',
      treeData: [
        {
          children: [
            {
              children: [
                {
                  children: [
                    {
                      children: [],
                      createTime: '2023-07-07 17:24:33',
                      deviceStatusVo: null,
                      id: '8',
                      latitude: null,
                      locationName: '402-2',
                      longitude: null,
                      pid: '4',
                      pids: '2,4',
                      relateDevice: null,
                      sortNum: 0,
                      updateTime: '2023-07-07 17:24:33',
                    },
                  ],
                  createTime: '2023-05-30 14:51:29',
                  deviceStatusVo: null,
                  id: '4',
                  latitude: null,
                  locationName: '电子商务产业园',
                  longitude: null,
                  pid: '2',
                  pids: '2',
                  relateDevice: null,
                  sortNum: 0,
                  updateTime: '2023-07-07 17:24:33',
                },
              ],
              createTime: '2023-05-30 14:48:01',
              deviceStatusVo: null,
              id: '2',
              latitude: null,
              locationName: '浙江杭州',
              longitude: null,
              pid: '0',
              pids: '0',
              relateDevice: null,
              sortNum: 0,
              updateTime: '2023-05-30 14:51:29',
            },
          ],
          createTime: null,
          deviceStatusVo: null,
          id: '0',
          latitude: null,
          locationName: '全部',
          longitude: null,
          pid: null,
          pids: null,
          relateDevice: null,
          sortNum: null,
          updateTime: null,
        },
      ],
      expandedKeys: [],
      //所有的按钮列表
      treeBtnList: [
        { name: '编辑', type: 'edit', class: 'icon-xiugai blue500' },
        { name: '新增', type: 'add', class: 'icon-xinzeng green500' },
        // { name: '批量新增', type: 'batch-add', class: 'icon-piliangdaoru blueGrey800' },
        // { name: '多层批量新增', type: 'mul-batch-add', class: 'icon-tree orange500' },
        { name: '删除', type: 'delete', class: 'icon-chushaixuanxiang red500' },
      ],
      deviceStatusObj: {
        '0': {
          text: '离线',
          class1: 'bg-red500',
          class2: 'red500',
          type: 'danger',
        },
        '1': {
          text: '在线',
          class1: 'bg-green500',
          class2: 'green500',
          type: 'success',
        },
        '-1': {
          text: '关闭中',
          class1: 'bg-orange500',
          class2: 'orange500',
          type: 'warning',
        },
        '-2': {
          text: '启动中',
          class1: 'bg-green500',
          class2: 'green500',
          type: 'primary',
        },
      },
      deviceObj: {},
      deviceList: [],
      fullTreeName: [],
    }
  },
  methods: {
    init() {
      this.deviceList = []
      this.deviceObj = {}
      if (this.options && this.options.length > 0) {
        this.treeData = this.options
        this.setting()
      } else {
        // this.getDataList()
      }
    },
    getDataList() {
      this.loadingTree = true
      this.$http
        .get(this.url)
        .then(({ data: res }) => {
          //this.loadingTree = false;
          if (res && res.code === 0) {
            this.treeData = res.data
            this.setting()
          } else {
            this.treeData = []
          }
        })
        .catch((err) => {
          //this.loadingTree = false;
          console.log('err', err)
        })
    },
    getDeviceObj(data) {
      if (data.length > 0) {
        data.map((item) => {
          if (item.deviceStatusVo) {
            this.deviceList.push(item)
            this.deviceObj[item.deviceStatusVo.id] = item.deviceStatusVo
          }
          if (item.children && item.children.length > 0) {
            this.getDeviceObj(item.children)
          }
        })
      }
    },
    setting() {
      if (this.expandedLevel !== 0) this.setExpandedKeys(this.treeData, 1)
      if (this.isShowDevice) this.getDeviceObj(this.treeData)
      if (this.defaultSelectFirst) {
        this.$nextTick(() => {
          this.$emit('treeItemClick', this.deviceList[0])
        })
      }
    },
    nodeClick(node, data) {
      if (this.$listeners['treeItemClick']) {
        this.$emit('treeItemClick', data)
      }
    },
    //节点选中状态发生变化时的回调
    handleCheckChange(data, checked, indeterminate) {
      if (!this.checkRadio) return
      if (checked) {
        this.$refs.tree.setCheckedKeys([data[this.defaultPropsNew.id]])
      }
    },
    nodeBtnHandle(type, node, data) {
      if (this.showButton && this.$listeners['nodeBtnHandle']) {
        this.$emit('nodeBtnHandle', {
          type: type,
          treeData: data,
          node,
        })
      }
    },
    nodeMouseenter(node, data) {
      // console.log("treeItemMouseover--node", node)
      // console.log("treeItemMouseover--data", data)
      this.$set(data, 'show', true)
    },
    nodeMouseleave(node, data) {
      this.$set(data, 'show', false)
    },
    setExpandedKeys(data, num) {
      if (data) {
        data.map((item) => {
          this.expandedKeys.push(item.id)
          if (num < this.expandedLevel) {
            if (item.children.length > 0) {
              this.setExpandedKeys(item.children, num + 1)
            }
          }
        })
      }
    },
    getCurrentNode() {
      return this.$refs.tree.getCurrentNode() || []
    },
    getCheckedNodes() {
      if (!this.showCheckbox) return []
      return this.$refs.tree.getCheckedNodes() || []
    },
    getCheckedKeys() {
      if (!this.showCheckbox) return []
      return this.$refs.tree.getCheckedKeys() || []
    },
    getHalfCheckedKeys() {
      if (!this.showCheckbox) return []
      return this.$refs.tree.getHalfCheckedKeys() || []
    },
    setCheckedKeys(val) {
      this.$refs.tree.setCheckedKeys(val)
    },
    filterNode(value, data) {
      if (!value) return true
      return data[this.defaultPropsNew.label].indexOf(value) !== -1
    },
    filter(value) {
      const traverse = (node) => {
        const childNodes = node.root ? node.root.childNodes : node.childNodes
        childNodes.forEach((child) => {
          child.visible = this.filterNode(value, child.data, child)
          traverse(child)
        })
        // node.visible为真，子节点也为真
        if (node.visible && node.childNodes.length > 0) {
          findChildNodes(node.childNodes)
        }
        // 递归循环子节点
        function findChildNodes(data) {
          for (let item of data) {
            item.visible = true
            if (item.childNodes.length) {
              return findChildNodes(item.childNodes)
            }
          }
        }
        if (!node.visible && childNodes.length) {
          let allHidden = true
          allHidden = !childNodes.some((child) => child.visible)
          if (node.root) {
            node.root.visible = allHidden === false
          } else {
            node.visible = allHidden === false
          }
        }
        if (!value) return
        if (node.visible && !node.isLeaf) node.expand()
      }
      traverse(this.$refs.tree.store)
    },
    getTreeName(id, sign) {
      if (!id) return
      this.fullTreeName = []
      this.treeName = ''
      this.$refs.tree.setCurrentKey(id)
      let obj = this.$refs.tree.getCurrentNode()
      return this.getFullTreeName(obj, sign)
    },
    getFullTreeName(node, sign = ' ') {
      if (node && node[this.defaultPropsNew.id] != this.topNodeId) {
        this.fullTreeName.push(node[this.defaultPropsNew.label])
        if (node.pid && node.pid != this.topNodeId) {
          let parent = this.$refs.tree.getNode(node.pid)
          if (parent) {
            return this.getFullTreeName(parent.data, sign)
          }
        }
      }
      return this.fullTreeName.reverse().join(sign)
      // this.treeName = this.fullTreeName.reverse().join(sign)
    },
    toDoSocket(d) {
      let data = JSON.parse(d)
      if (data.type == 'ONLINE' || data.type == 'OFFLINE') {
        this.deviceObj[data.data.deviceId].deviceStatus =
          data.type == 'ONLINE' ? 1 : 0
      }
    },
  },
}
</script>

<style lang="scss" scoped>
.treeDiv {
  height: calc(100vh - 220px);
  overflow-y: auto;

  .iconfont {
    font-size: 20px;
  }
}

.treeBtn {
  .iconfont {
    font-size: 14px;
    margin: 0 4px;
  }
}
</style>
